💡 AI 인사이트

🤖 AI가 여기에 결과를 출력합니다...

댓글 커뮤니티

쿠팡이벤트

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

검색

    로딩 중이에요... 🐣

    [코담] 웹개발·실전 프로젝트·AI까지, 파이썬·장고의 모든것을 담아낸 강의와 개발 노트

    22 Viewset 권한 설정 & 관리자 vs 일반 사용자 | ✅ 편저: 코담 운영자

    22-Viewset 권한 설정 & 관리자 vs 일반 사용자

    - Viewset 권한 설정 & 관리자 vs 일반 사용자

    🔗 소스 1: bugbytes-io/drf-course-api

    🔗 소스 2: braverokmc79/Django_REST_Framework_Series


    1. 개요

    이번 강의에서는 Django REST Framework의 ViewSet에서 관리자(admin)일반 사용자(user) 간의 접근 권한을 어떻게 나누고 제어 하는지를 배웁니다. 인증된 사용자라 하더라도 본인이 아닌 다른 사용자의 데이터를 조회하거나 수정하는 것을 방지하기 위한 필터링 및 권한 설정을 실습 합니다.


    2. 현재 ViewSet 기본 설정 복습

    class OrderViewSet(viewsets.ModelViewSet):
        queryset = Order.objects.prefetch_related('items__product')
        serializer_class = OrderSerializer
        permission_classes = [IsAuthenticated]
        pagination_class = None
        filterset_class = OrderFilter
        filter_backends = [DjangoFilterBackend]
    
        @action(
            detail=False,            
            methods=['get'],          
            url_path='user-orders',  
        )
    
        def user_orders(self, request):
            filtered_qs = self.filter_queryset(self.get_queryset())
            orders = filtered_qs.filter(user=request.user)  
            serializer = self.get_serializer(orders, many=True)  
            return Response(serializer.data)
    
    • 현재는 인증된 사용자만 모든 주문을 조회할 수 있음
    • 관리자뿐만 아니라 일반 사용자도 모든 주문을 볼 수 있어 보안상 문제가 발생함

    3. 문제 상황 예시

    • 일반 사용자 A가 /orders/ 또는 /orders/<order_id>/에 접근하면 다른 사람의 주문까지 조회됨
    • 프론트엔드에서는 사용자 개인 페이지에서 본인의 주문만 보여야 하는데, 백엔드에서 필터링이 되지 않음

    4. 해결 전략: get_queryset() 오버라이딩

    get_queryset() 메서드를 오버라이딩하여 사용자 타입에 따라 응답 데이터를 제한합니다.

    class OrderViewSet(viewsets.ModelViewSet):
        # 기본적으로 Order와 관련된 items.product까지 함께 불러옴 (쿼리 최적화)
        queryset = Order.objects.prefetch_related('items__product')
        
        serializer_class = OrderSerializer
        permission_classes = [IsAuthenticated]  # 로그인된 사용자만 접근 가능
        pagination_class = None  # 페이징 비활성화
        filterset_class = OrderFilter  # 필터셋 클래스 지정
        filter_backends = [DjangoFilterBackend]  # 필터 백엔드 활성화
    
        def get_queryset(self):
            """
            관리자: 전체 주문 조회 가능
            일반 사용자: 본인 주문만 조회 가능
            """
            qs = super().get_queryset()  # 기본 queryset 가져오기
            if not self.request.user.is_staff:
                # 일반 사용자일 경우 본인 주문만 필터링
                qs = qs.filter(user=self.request.user)
            return qs
    
    
    • is_staff가 False인 일반 사용자에겐 본인의 주문만 응답
    • 관리자는 모든 주문 데이터 접근 가능

    정렬 및 검색 필터 확인

    http://127.0.0.1:8000/orders/?status=Confirmed

    http://127.0.0.1:8000/orders/?created_at_after=2025-06-24&created_at_before=2025-06-24


    5. 효과 확인

    • 브라우저 기반 API 혹은 VSCode REST Client를 통해 테스트
    • 일반 사용자로 요청 시 자신의 주문만 반환됨
    • 다른 사람의 주문 ID로 상세 요청 시 404 Not Found 응답
    GET /orders/   # 일반 사용자: 본인 주문만 응답
    GET /orders/<other_user_order_id>/   # 일반 사용자: 404 응답
    

    🎈테스트 하기

    1. 장과 관리자 화면에서 테스트 유저 등록 후 주문 처리

    테스트유저등록

    1. insomnia 로 일반 사용자 테스트 일반사용자

    2. 관리지 관리자


    6. 커스텀 액션 제거 가능

    기존에 @action(detail=False)으로 정의했던 user-orders 액션은 불필요

    • 이유: 기본 /orders/ 요청 자체가 사용자에 따라 자동 필터링되기 때문

    7. 전체 구성 요약

    • permission_classes = [IsAuthenticated]: 인증된 사용자만 API 접근 가능
    • get_queryset() 오버라이딩으로 일반 사용자에겐 데이터 접근 제한
    • 관리자는 모든 주문을 자유롭게 조회, 수정, 삭제 가능
    • ViewSet 하나로 사용자 유형별 데이터 접근 권한 제어 완성

    8. 마무리 및 다음 강의 예고

    이번 강의를 통해 ViewSet 하나로 권한 제어, 필터링, 보안까지 통합 관리하는 방법을 익혔습니다.

    다음 강의에서는 중첩 Serializer와 관련 객체를 포함한 POST 요청 처리 및 create() 메서드 오버라이딩에 대해 학습합니다.

    TOP
    preload preload